import axios from "axios";
import { Message } from "element-ui";
import store from "@/store";
import router from "@/router";
import { getTimeStamp } from "@/utils/auth";
//  这里的代码和 vue 没有关联 所以不能直接使用 this.$store
// 在 vue 组件里面  this.$store 就是等于导入的 store

const TimeOut = 3600; // 定义超时时间

const service = axios.create({
  // 如果执行 npm run dev 值为 /api 正确  /api 这个代理只是给开发环境配置的代理
  //  如果执行 npm run build 值为 /prod-api 运维在上线的时候 会配置上 /prod-api 的代理
  baseURL: process.env.VUE_APP_BASE_API, // url = base url + requedt url
  timeout: 5000 // 超时时间
}); // 创建一个 axios 实例

// // 添加请求拦截器   主要处理 token 的统一注入问题
service.interceptors.request.use(
  config => {
    // config  是请求配置的信息
    // 在这个位置需要统一的去注入 token
    if (store.getters.token) {
      // 只有在有 token 的情况下，才有必要去检查时间戳是否超时
      if (IsCheckTimeOut()) {
        // 如果他为 true  表示过期了
        //  token 没用了 因为超时了
        store.dispatch("user/logout"); // 执行登出操作
        //  跳转到登录页面
        router.push("/login");
        return Promise.reject(new Error("token超时了"));
      }

      // 如果 token 存在  注入 token  统一携带 token
      //  config.headers["Authorization"]   ===   config.headers.Authorization
      config.headers["Authorization"] = `Bearer ${store.getters.token}`;
    }

    return config; // 必须返回配置
  },
  error => {
    // console.log(111);
    return Promise.reject(error);
  }
);

// 添加响应拦截器  主要处理返回的数据异常 和 数据结构问题
service.interceptors.response.use(
  response => {
    // axios 默认加了一层 data
    const { success, message, data } = response.data;
    // 要根据 success 的成功与否决定下面的操作
    // console.log(success);
    if (success) {
      return data;
    } else {
      //  业务已经错误了  不能进 then  应该进 catch
      Message.error(message); // 提示错误信息
      //  此处因为响应已经成功  所以没有错误对象，需要重新 new 一个错误对象
      return Promise.reject(new Error(message));
    }
  },
  error => {
    if (
      error.response &&
      error.response.data &&
      error.response.data.code === 10002
    ) {
      // 当等于 10002 时  表示后端返回超时了
      store.dispatch("user/logout"); // 登出 action 删除 token
      router.push("/login");
    } else {
      Message.error(error.message); // 提示错误信息
    }
    return Promise.reject(error); // 返回执行错误  让当前的执行链跳出成功  直接进入 catch
  }
);

// 是否超时
// 超时逻辑  (当前时间  -  缓存中的时间)  是否大于时间差
function IsCheckTimeOut() {
  var currentTime = Date.now(); // 当前时间戳
  var timeStamp = getTimeStamp(); // 缓存时间戳
  return (currentTime - timeStamp) / 1000 > TimeOut;
}

export default service; // 导出 axios 实例
